const path = require("path");
const fs = require("fs-extra");
const Chalk = require("chalk");
const { exec } = require("child_process");
const { _createOnlineWH } = require("./aio/api");
const FormData = require("form-data");
const { _getPromise, _getUuidCode } = require("./utils");
const { COMPONENT_TYPE } = require("./config");

let haveOnlineWH = false; // 是否需要创建对应的线上仓库

if (getConfigJSON("ACCESS_TOKEN")) haveOnlineWH = true;

module.exports = (name, { force, online }, type) => {
  // 判断重名
  const currentPath = process.cwd();
  const newComponentPath = path.join(currentPath, name);
  const existingDir = fs.existsSync(newComponentPath);
  if (existingDir) {
    console.log(Chalk.yellowBright("检测到此路径已被占用.."));
    if (!force) {
      return;
    }
    // 删除原文件
    deleteOldDir(newComponentPath);
    console.log(Chalk.yellowBright("原路径文件已删除.."));
  }
  // 初始化新模板仓库
  initNewWarehouse(name, type, online);
  // 接收变量传递给package.json
};

function deleteOldDir(_path) {
  let files = fs.readdirSync(_path);
  if (files.length === 0) {
    fs.rmdirSync(_path);
    return;
  }
  files.forEach((item) => {
    const itemPath = path.join(_path, item);
    const itemState = fs.lstatSync(itemPath);
    const isDir = itemState.isDirectory();
    if (isDir) {
      deleteOldDir(itemPath);
    } else {
      fs.unlinkSync(itemPath);
    }
  });
  fs.rmdirSync(_path);
}

function initNewWarehouse(name, type, online) {
  const { warehouseSrc: WHURL, branch: WHBRANCH } = COMPONENT_TYPE.find(
    (item) => item.type === type
  );
  const getUrl = `${WHURL} ${name}`;
  const cloneOrder = `git clone ${getUrl} ${WHBRANCH ? "-b " + WHBRANCH : ""}`;
  const installOrder = `cd ${name} && npm i`;
  const removeRemoteOrder = `cd ${name} && git remote remove origin`;
  const renameBranchOrder = `cd ${name} && git branch -m ${WHBRANCH} origin`;
  const cloneMessage = Chalk.greenBright("模板下载完成..");
  const installMessage = Chalk.greenBright("依赖安装完成..");
  _exec(cloneOrder, cloneMessage)
    .then(() => _exec(installOrder, installMessage))
    .then(() => _exec(WHBRANCH ? removeRemoteOrder : null))
    .then(() => _exec(WHBRANCH ? renameBranchOrder : null))
    .then(() => replaceKey(name))
    .then(() => createOnlineWarehouse(name, online))
    .then((path) => addRemotePath(path, online))
    .then(() => hasBeenCreated())
    .catch((err) => {
      console.log("创建失败：", err);
    });
}

// 执行命令
function _exec(order, message) {
  if (!order) return Promise.resolve();
  const { promise, resolve, reject } = _getPromise();
  let t = exec(order);
  t.on("exit", (code) => {
    resolve(code);
    message && console.log(message);
  });
  return promise;
}

/**
 * 项目中替换关键字
 */
function replaceKey(name) {
  const { promise, resolve, reject } = _getPromise();
  const targetPath = path.join(process.cwd(), name);
  process.chdir(targetPath);
  const packageName = "package.json";
  const packagePath = path.join(targetPath, packageName);
  const havepackage = fs.existsSync(packagePath);
  if (!havepackage) {
    console.log(Chalk.redBright("package.json配置关键字失败，未找到文件"));
    reject();
    return;
  }
  let content = fs.readFileSync(packagePath, "utf8");
  content = content.replace(/PACKAGE_NAME/g, name);
  fs.writeFileSync(packagePath, content, "utf8");
  resolve();
  return promise;
}

/**
 * 创建线上仓库
 * 判断「执行此步骤」或「略过」
 */
function createOnlineWarehouse(name, online) {
  if (!haveOnlineWH || !online) {
    return Promise.resolve();
  }
  const { promise, resolve, reject } = _getPromise();
  const formData = new FormData();
  const headers = formData.getHeaders();
  formData.append("name", name);
  formData.append("access_token", getConfigJSON("ACCESS_TOKEN"));
  _createOnlineWH(formData, headers).then(
    (res) => {
      console.log(Chalk.greenBright("gitee新仓库创建完成.."));
      const { html_url } = JSON.parse(res);
      resolve(html_url);
    },
    (err) => {
      const { status } = err;
      if (status === 422) {
        console.log(
          Chalk.yellowBright("检测到gitee仓库中已存在同名仓库，重新命名..")
        );
        let newName = name + _getUuidCode(getConfigJSON("WH_NAME_HASH_LENGTH"));
        resolve(createOnlineWarehouse(newName, online));
      } else {
        console.log(Chalk.redBright("未知错误.."));
        reject();
      }
    }
  );
  return promise;
}

/**
 * 项目添加线上仓库索引
 * 判断「执行此步骤」或「略过」
 */
function addRemotePath(path, online) {
  if (!haveOnlineWH || !online) {
    return Promise.resolve();
  }
  const addRemoteOrder = `git remote add origin ${path}`;
  return _exec(addRemoteOrder);
}

/**
 * 创建完成
 */
function hasBeenCreated() {
  console.log(Chalk.cyan("项目创建完成。"));
  return Promise.resolve();
}

/**
 * 创建失败
 */
function createAFailure() {
  console.log(Chalk.redBright("项目创建失败。"));
  return Promise.resolve();
}

/**
 * 获取最新config
 */
function getConfigJSON(key) {
  const configPath = path.join(__dirname, "../config/config.json");
  let data = fs.readFileSync(configPath, "utf8");
  return JSON.parse(data)[key];
}
